package com.lk.sys.service.realm;

import com.lk.sys.dao.SysUserDao;
import com.lk.sys.entity.SysUsr;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.apache.shiro.util.ByteSource.Util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class ShiroUserRealm extends AuthorizingRealm {
    @Autowired
    private SysUserDao sysUserDao;
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        return null;
    }

    /**基于此方法的返回值，告诉shiro我们采用什么加密算法
     * 从浏览器中获取的密码要进行加密后再与数据库中的加密的密码进行比较，*/
    @Override
    public CredentialsMatcher getCredentialsMatcher() {
        HashedCredentialsMatcher cMatcher = new HashedCredentialsMatcher();
        //用什么算法进行加密
        cMatcher.setHashAlgorithmName("MD5");
        //加密次数
        cMatcher.setHashIterations(1);
        return cMatcher;
    }

    /**负责认证信息的获取及封装*/
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //1。获取登陆用户信息（用户登陆界面输入的用户名）
        UsernamePasswordToken uToken = (UsernamePasswordToken) token;
        String username = uToken.getUsername();
        //char[] password = uToken.getPassword();
        //2。基于用户名查询数据库，找到用户对象，并进行判断
        //2。1获取用户对象
        SysUsr user = sysUserDao.findUserByUsername(username);
        //2。2验证对象是否存在
        if (user == null) throw new UnknownAccountException();
        //2。3查看用户是否被禁用
        if (user.getValid() == 0) throw new LockedAccountException();
        //3。封装用户信息
        ByteSource credentialsSalt = ByteSource.Util.bytes(user.getSalt().getBytes());
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(
                user,//用户身份
                user.getPassword(), //已加密的密码
                credentialsSalt, //盐值，凭证盐，与保存是的盐值要一致
                this.getName());//realm的名字
        return info;
    }
}
